package astoliarskyi.lab5;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class ConnectionPool {
	
	private final static int CONNECTIONS_AMOUNT = 30;
	private final static int WAITING_TIMEOUT = 1000;
	private final static int IDLE_TIMEOUT = 500;

	private final Queue<Connection> connAvailable = new ConcurrentLinkedQueue<Connection>();
	
	private final Semaphore available = new Semaphore(CONNECTIONS_AMOUNT, true);
	
	public ConnectionPool(String url, String user, String passwd){
		for (int i=0; i<CONNECTIONS_AMOUNT; i++){
			try {
				Connection conn = DriverManager.getConnection(url, user, passwd);
				connAvailable.add(conn);
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}
	
	public Connection checkout() throws TimeoutException{
		boolean connAcquired = false;
		Connection conn = null;
		try {
			connAcquired = available.tryAcquire(WAITING_TIMEOUT, TimeUnit.MILLISECONDS);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		if (connAcquired){
			conn = connAvailable.poll();
		} else {
			throw new TimeoutException();
		}
		return conn;
	}
	
	public void checkin(Connection c){
		connAvailable.add(c);
		available.release();
	}
}